package cn.hg.jbsa.admin.provider;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.SqlPara;

import cn.hg.jboot.core.BeanStatus;
import cn.hg.jboot.core.exception.BaseServiceException;
import cn.hg.jbsa.admin.model.JbsaAdmin;
import cn.hg.jbsa.admin.model.JbsaResource;
import cn.hg.jbsa.admin.service.JbsaResourceService;
import cn.hutool.core.text.CharSequenceUtil;
import io.jboot.aop.annotation.Bean;
import io.jboot.db.model.Columns;
import io.jboot.service.JbootServiceBase;

@Bean
public class JbsaResourceServiceProvider extends JbootServiceBase<JbsaResource> implements JbsaResourceService {

    @Override
    public List<JbsaResource> buildTree (final List<JbsaResource> list, Integer... parentIds) throws BaseServiceException {
        List<JbsaResource> tree = new ArrayList<>();

        for (JbsaResource bean : list) {

            for (Integer id : parentIds) {
                if (id.equals(bean.getParentId())) {
                    tree.add(bean);
                }
            }

        }

        for (JbsaResource bean : tree) {
            bean.put("children", this.buildTree(list, bean.getId()));
        }

        tree.sort(new Comparator<JbsaResource>() {

            @Override
            public int compare (JbsaResource o1, JbsaResource o2) {
                return o1.getSortNum().compareTo(o2.getSortNum());
            }

        });

        return tree;
    }

    @Override
    public List<JbsaResource> findActionByAdmin(JbsaAdmin admin, String status) {
        Kv para = Kv.by("admin", admin).set("type", "action").set("status", status);

        List<JbsaResource> permissionList = new ArrayList<>();

        // 通过SQL模板引擎构建SQL及参数
        SqlPara sqlPara = Db.getSqlPara("system.findResourceByAdmin", para);
        List<JbsaResource> resourceList = JbsaResource.dao.find(sqlPara);

        for (JbsaResource resource : resourceList) {

            if (CharSequenceUtil.isBlank(resource.getValue()) || !CharSequenceUtil.equals("action", resource.getType())) {
                continue;
            }

            permissionList.add(resource);

        }

        sqlPara = Db.getSqlPara("system.findResourceByOrg", para);
        List<JbsaResource> resourceList2 = JbsaResource.dao.find(sqlPara);
        for (JbsaResource resource : resourceList2) {

            if (StrKit.isBlank(resource.getValue()) || !CharSequenceUtil.equals("action", resource.getType())) {
                continue;
            }

            permissionList.add(resource);

        }

        return permissionList;
    }

    @Override
    public List<JbsaResource> findMenuByAdmin(JbsaAdmin admin, String status, Integer... parentIds) {
        Kv para = Kv.by("admin", admin).set("type", "menu").set("status", status);

        // 通过SQL模板引擎构建SQL及参数
        SqlPara sqlPara = Db.getSqlPara("system.findResourceByAdmin", para);
        List<JbsaResource> resourceList = JbsaResource.dao.find(sqlPara);

        resourceList = this.buildTree(resourceList, parentIds);

        return resourceList;
    }

    @Override
    public List<JbsaResource> findPageByKv(Integer page, Integer limit, Kv para) throws BaseServiceException {
        SqlPara sqlPara = Db.getSqlPara("system.findResource", para);

        @SuppressWarnings("unchecked")
        List<JbsaResource> list = this.getDao().find(sqlPara);

        return list;
    }

    @Override
    public List<JbsaResource> findTree (Integer... parentIds) throws BaseServiceException{
        List<JbsaResource> tree = new ArrayList<>();

        List<JbsaResource> list = this.findListByColumns(Columns.create("status", BeanStatus.on.name()));
        tree = this.buildTree(list, parentIds);

        JbsaResource bean = new JbsaResource();
        bean.setId(0);
        bean.setName("-- 顶层 --");
        bean.setStatus("on");
        bean.setType("company");
        bean.setCreatorId(1);
        bean.setEditorId(1);
        bean.setLayerNum(0);

        tree.add(0, bean);

        return tree;
    }

    @Override
    public void updateChildredIds(JbsaResource resource) {
        if (null == resource) {
            return;
        }

        String childrenIds = Db.queryFirst(
            "SELECT GROUP_CONCAT(id) FROM jbsa_resource WHERE status <> ? AND parent_id=?", BeanStatus.del.name(), resource.getId());
        resource.setChildrenIds(childrenIds);
        this.saveOrUpdate(resource);
    }

    @Override
    public void updateStatus(JbsaResource resource, String status) {
        this.updateStatusWithChildren(resource, status);
    }

    private void updateStatusWithChildren (JbsaResource bean, String status) {
        if (!CharSequenceUtil.equals(bean.getStatus(), status)) {
            bean.setStatus(status);
            this.update(bean);
        }

        List<JbsaResource> childrenList = this.findListByColumns(Columns.create("parent_id", bean.getId())
            .ne("status", BeanStatus.del.name()));

        for (JbsaResource child : childrenList) {
            if (!CharSequenceUtil.equals(child.getStatus(), status)) {
                child.setStatus(status);
                this.update(child);
            }
            this.updateStatusWithChildren(child, status);
        }

    }
}
